package xaj.meta.visit;

import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.frontend.Job;
import polyglot.types.SemanticException;
import polyglot.types.TypeSystem;
import polyglot.visit.ErrorHandlingVisitor;
import polyglot.visit.NodeVisitor;
import xaj.scc.ast.ClosureFactor;
import xaj.scc.ast.ConcatFactor;
import xaj.scc.ast.Factor;
import xaj.scc.ast.GrammarNodeOld;
import xaj.scc.ast.ImportSymbol;
import xaj.scc.ast.ImportSyntax;
import xaj.scc.ast.LambdaFactor;
import xaj.scc.ast.NamedFactor;
import xaj.scc.ast.NumberOfPasses;
import xaj.scc.ast.OnWeaving;
import xaj.scc.ast.OptionalFactor;
import xaj.scc.ast.OrFactor;
import xaj.scc.ast.Production;
import xaj.scc.ast.ProductionElement;
import xaj.scc.ast.SemanticAction;
import xaj.scc.ast.SimpleFactor;
import xaj.scc.ast.StringFactor;
import xaj.scc.ast.SyntaxClassBody;
import xaj.scc.ast.SyntaxClassDecl;
import xaj.scc.ast.SyntaxDeclaration;
import xaj.scc.ast.SyntaxDeclarationInsertion;
import xaj.scc.ast.SyntaxDeclarationOverrides;
import xaj.scc.ast.Visitable;
import xaj.scc.ast.Visitor;

public class XAJVisitor
extends ErrorHandlingVisitor
implements Visitor {

	public enum VisitType {ENTER, LEAVE};
	
	private VisitType visitType;
	
	public VisitType getVisitType() {
		return visitType;
	}
	
	private Node nodeChanged;
	private XAJVisitor visitorChanged;
	
	public void changeNode(Node n) throws Error {
		if (getVisitType() != VisitType.LEAVE) {
			throw new Error("Nodes can be changed only in LEAVE mode");
		}
		nodeChanged = n;
	}
	
	public void changeVisitor(XAJVisitor v)  throws Error {
		if (getVisitType() != VisitType.ENTER) {
			throw new Error("Visitors can be changed only in ENTER mode");
		}
		visitorChanged = v;
	}
	
	public XAJVisitor(Job job, TypeSystem typeSystem, NodeFactory nodeFactory) {
		super(job, typeSystem, nodeFactory);
	}

    public NodeVisitor enterCall(Node parent, Node n) {
    	visitorChanged = this;
    	if (n instanceof Visitable) {
//    		System.out.println("Enter: " + n.getClass().getName());
    		visitType = VisitType.ENTER;
    		((Visitable) n).accept(this);
    	}
        return visitorChanged;
    }

	protected Node leaveCall(Node old, Node n, NodeVisitor v) throws SemanticException {
		nodeChanged = n;
    	if (n instanceof Visitable) {
//    		System.out.println("Leave: " + n.getClass().getName());
    		visitType = VisitType.LEAVE;
    		((Visitable) n).accept((XAJVisitor) v);
    	}
        return nodeChanged;
	}

	@Override
	public void visitClosureFactor(ClosureFactor cf) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitConcatFactor(ConcatFactor cf) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitFactor(Factor f) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitGrammarNodeOld(GrammarNodeOld g) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitImportSymbol(ImportSymbol is) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitImportSyntax(ImportSyntax is) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitNamedFactor(NamedFactor nf) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitNumberOfPasses(NumberOfPasses np) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitOptionalFactor(OptionalFactor of) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitOrFactor(OrFactor of) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitProduction(Production pd) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitProductionElement(ProductionElement pe) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSemanticAction(SemanticAction sa) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSimpleFactor(SimpleFactor sf) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitStringFactor(StringFactor sf) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSyntaxClassBody(SyntaxClassBody scb) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSyntaxClassDecl(SyntaxClassDecl scd) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSyntaxDeclaration(SyntaxDeclaration sd) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSyntaxDeclarationInsertion(SyntaxDeclarationInsertion sdi) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitSyntaxDeclarationOverrides(SyntaxDeclarationOverrides sdo) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visitLambdaFactor(LambdaFactor lf) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	//public void visitOnWeaving(OnWeaving ow) {
	public void visit(OnWeaving ow) {
		// TODO Auto-generated method stub
		
	}


}
